/**
 * Software License, Version 1.0
 *
 * Copyright 2003 The Trustees of Indiana University.  All rights reserved.
 *
 *
 *Redistribution and use in source and binary forms, with or without
 *modification, are permitted provided that the following conditions are met:
 *
 *1) All redistributions of source code must retain the above copyright notice,
 * the list of authors in the original source code, this list of conditions and
 * the disclaimer listed in this license;
 *2) All redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the disclaimer listed in this license in
 * the documentation and/or other materials provided with the distribution;
 *3) Any documentation included with all redistributions must include the
 * following acknowledgement:
 *
 *"This product includes software developed by the Community Grids Lab. For
 * further information contact the Community Grids Lab at
 * http://communitygrids.iu.edu/."
 *
 * Alternatively, this acknowledgement may appear in the software itself, and
 * wherever such third-party acknowledgments normally appear.
 *
 *4) The name Indiana University or Community Grids Lab or NaradaBrokering,
 * shall not be used to endorse or promote products derived from this software
 * without prior written permission from Indiana University.  For written
 * permission, please contact the Advanced Research and Technology Institute
 * ("ARTI") at 351 West 10th Street, Indianapolis, Indiana 46202.
 *5) Products derived from this software may not be called NaradaBrokering,
 * nor may Indiana University or Community Grids Lab or NaradaBrokering appear
 * in their name, without prior written permission of ARTI.
 *
 *
 * Indiana University provides no reassurances that the source code provided
 * does not infringe the patent or any other intellectual property rights of
 * any other entity.  Indiana University disclaims any liability to any
 * recipient for claims brought by any other entity based on infringement of
 * intellectual property rights or otherwise.
 *
 *LICENSEE UNDERSTANDS THAT SOFTWARE IS PROVIDED "AS IS" FOR WHICH NO
 *WARRANTIES AS TO CAPABILITIES OR ACCURACY ARE MADE. INDIANA UNIVERSITY GIVES
 *NO WARRANTIES AND MAKES NO REPRESENTATION THAT SOFTWARE IS FREE OF
 *INFRINGEMENT OF THIRD PARTY PATENT, COPYRIGHT, OR OTHER PROPRIETARY RIGHTS.
 *INDIANA UNIVERSITY MAKES NO WARRANTIES THAT SOFTWARE IS FREE FROM "BUGS",
 *"VIRUSES", "TROJAN HORSES", "TRAP DOORS", "WORMS", OR OTHER HARMFUL CODE.
 *LICENSEE ASSUMES THE ENTIRE RISK AS TO THE PERFORMANCE OF SOFTWARE AND/OR
 *ASSOCIATED MATERIALS, AND TO THE PERFORMANCE AND VALIDITY OF INFORMATION
 *GENERATED USING SOFTWARE.
 */

package cgl.narada.wsinfra.wsr.impl;

import cgl.narada.wsinfra.schemas.addressing.ActionDocument;
import cgl.narada.wsinfra.schemas.addressing.EndpointReferenceType;
import cgl.narada.wsinfra.schemas.addressing.FaultToDocument;
import cgl.narada.wsinfra.schemas.addressing.FromDocument;
import cgl.narada.wsinfra.schemas.addressing.RelatesToDocument;
import cgl.narada.wsinfra.schemas.addressing.ReplyAfterDocument;
import cgl.narada.wsinfra.schemas.addressing.ReplyToDocument;
import cgl.narada.wsinfra.schemas.soap.EnvelopeDocument;
import cgl.narada.wsinfra.schemas.wsr.ResponseDocument;
import cgl.narada.wsinfra.util.SoapMessageAlteration;
import cgl.narada.wsinfra.util.XmlContentTransfer;
import cgl.narada.wsinfra.wsa.AddressingHeaders;
import cgl.narada.wsinfra.wsa.WsaEnvelopeCreator;
import cgl.narada.wsinfra.wsa.WsaEprRules;
import cgl.narada.wsinfra.wsa.WsaProcessingFactory;
import cgl.narada.wsinfra.wsr.WsrActions;
import cgl.narada.wsinfra.wsr.WsrElementCreation;
import cgl.narada.wsinfra.wsr.WsrProcessingFactory;
import cgl.narada.wsinfra.wsr.WsrQNames;
import cgl.narada.wsinfra.wsr.WsrResponseCreator;


/** This class is will create response document
 
   @author Damodar Yemme
   Created on February 23, 2005, 10:08 AM
   $Revision: 1.7 $
   
 */
public class WsrResponseCreatorImpl implements WsrResponseCreator{
    private static final WsrResponseCreator instance =
            new WsrResponseCreatorImpl();
    
    private WsrActions wsrActions;
    private WsaEprRules wsaEprRules;
    private WsrQNames wsrQNames;
    
    private WsaEnvelopeCreator wsaEnvelopeCreator;
    private SoapMessageAlteration soapMessageAlteration;
    private XmlContentTransfer xmlContentTransfer;
    
    private WsrElementCreation wsrElementCreation;
    private String moduleName = "WsrResponseCreator: ";
    
    /** Creates a new instance of WsrResponseCreatorImpl */
    private WsrResponseCreatorImpl() {
        wsrActions = WsrActions.getInstance();
        wsaEprRules = WsaProcessingFactory.getWsaEprRules();
        wsaEnvelopeCreator = WsaProcessingFactory.getWsaEnvelopeCreator();
        soapMessageAlteration = SoapMessageAlteration.getInstance();
        xmlContentTransfer = XmlContentTransfer.getInstance();
        wsrElementCreation = WsrProcessingFactory.getWsrElementCreation();
    }
    /**This method returns instancs of this class*/
    public static WsrResponseCreator getInstance() {
        return instance;
    }
   
    /**This method adds the response element to the same envelopes document 
     * in the header  */
    public void addResponse(EnvelopeDocument envelopeDocument, 
    		                ResponseDocument responseDocument){
        
        
        soapMessageAlteration.addToSoapHeaderAsLastChild(envelopeDocument, 
        		                                         responseDocument);
        
    }   
    public EnvelopeDocument
	  getResponse(AddressingHeaders addressingHeaders,
				    EndpointReferenceType wsrSinkEpr) {
	    EndpointReferenceType to = 
	      wsaEprRules.sendTo(addressingHeaders);
	    if (to == null) {
	      System.out.println(moduleName + 
				 "No idea where to send the response to");
	      return null;
	    }

	    if (!addressingHeaders.hasMessageID()) {
	      System.out.println(moduleName + 
				 "The received message has NO valid messageID");
	      return null;
	    }
	    
	    FromDocument from = FromDocument.Factory.newInstance();
	    from.setFrom(wsrSinkEpr);

	    ActionDocument action = ActionDocument.Factory.newInstance();
	    action.addNewAction().setStringValue(wsrActions.getProcessResponse());

	    FaultToDocument faultTo = FaultToDocument.Factory.newInstance();
	    faultTo.setFaultTo(wsrSinkEpr);

	    String messageId = 
	    	addressingHeaders.getMessageID().getMessageID().getStringValue();
	    RelatesToDocument relatesTo = RelatesToDocument.Factory.newInstance();
	    relatesTo.addNewRelatesTo().setStringValue(messageId);
	    
	    
	    EnvelopeDocument envelopeDocument = 
	      wsaEnvelopeCreator.createSoapEnvelope(to, from, action, relatesTo);	    
	    return envelopeDocument;
	  }
    
    /** Gets the EnvelopeDocument containing Simple Response Document
    In Header of the EnvelopeDocument
    Wsa:To Element would be replyTo
    Wsa:From Element would be wsrSinkEpr and
    Wsa:Action Element would be processResponse
    This method is used when replyTo element is present in 
    <Request> element and when replypattern would be Callback
    or <PollRequest> element when replyTo element is present
    */
   public EnvelopeDocument getResponse(EndpointReferenceType wsrSinkEpr,
   		                            EndpointReferenceType wsrSourceEpr){
       if (wsrSourceEpr == null) {
           System.out.println(moduleName + "The <To> element cannot be NULL");
           return null;
       }
       if (wsrSinkEpr == null) {
           System.out.println(moduleName + "The <From> Should NOT be null");
           return null;
       }
       FromDocument from = FromDocument.Factory.newInstance();
       from.setFrom(wsrSinkEpr);
    
       ActionDocument action = ActionDocument.Factory.newInstance();
       action.addNewAction().setStringValue(wsrActions.getProcessResponse());
    
       ReplyToDocument replyTo = ReplyToDocument.Factory.newInstance();
       replyTo.setReplyTo(wsrSinkEpr);
    
       ReplyAfterDocument replyAfter = null;
    
       FaultToDocument faultTo = null;
       ResponseDocument responseDocument = wsrElementCreation.newResponse();
       if(responseDocument != null){
           EnvelopeDocument envelopeDocument =
                wsaEnvelopeCreator.createSoapEnvelope(wsrSourceEpr, from, action,
                                             replyTo, replyAfter, faultTo);
        
           soapMessageAlteration.addToSoapHeaderAsLastChild(
           		                       envelopeDocument, responseDocument);
           return envelopeDocument;
       } else{
           return null;
       }
   }
}
